﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Linq; //string.Contains(char)
using System.Web;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;

namespace ExportTools
{
	/// <summary>
	/// Summary description for CommonExport
	/// </summary>
	public class CommonExport
	{
		private CommonExport()
		{
		}

		private static string[] ColumnSpanEnumeration = new string[] { };
		private static Dictionary<int, int> headerInfo = null;
		public static Dictionary<int, int> ParseColumnSpanInfo(string[] columnSpanInput)
		{
			headerInfo = new Dictionary<int, int>();
			string[] spans = columnSpanInput;
			int delay = 0, max = -1;
			foreach (string span in spans)
				if (!string.IsNullOrEmpty(span))
				{
					if (span.Contains(':'))
					{
						string[] parts = span.Split(':');
						int startAt = int.Parse(parts[0]) - 1;
						if (startAt <= max)
							throw new ApplicationException("Ordinea coloanelor defalcate este incorecta!");
						startAt += delay;
						max = startAt;
						int length = int.Parse(parts[1]);
						delay += length - 1;
						headerInfo.Add(startAt, length);
						for (int x = 1; x < length; ++x)
							headerInfo.Add(startAt + x, 0);
					}
					else
					{
						int value = int.Parse(span) - 1;
						if (value <= max)
							throw new ApplicationException("Ordinea coloanelor defalcate este incorecta!");
						value += delay;
						max = value;
						++delay;
						headerInfo.Add(value, 2);
						headerInfo.Add(value + 1, 0);
					}
				}
			return headerInfo;
		}
		private static Dictionary<int, int> HeaderInfo
		{
			get
			{
				if (headerInfo == null)
				{
					headerInfo = ParseColumnSpanInfo(ColumnSpanEnumeration);
				}
				return headerInfo;
			}
		}

		/// <param name="detailedEmptyTable">Will return the possible contents of an empty report.
		///		Can be discarded, if a clean page is required.
		///		Can be added multiple times: see DuplicateControl.
		///	</param>
		public static HtmlGenericControl CreateHtmlObject(string strProcedureName, string strDateStart, string strDateEnd, string strReportID,
			out string header, out string title, out string footer, out HtmlGenericControl detailedEmptyTable)
		{
			DataSet ds_Reports = Hipocrate.DB.DBConnection.GetData(strProcedureName, new string[] { "ID" }, new object[] { strReportID });
			DataView dvReportMetadata = ds_Reports.Tables[1].DefaultView;

			if (string.IsNullOrEmpty(strDateStart))
				strDateStart = DateTime.Now.ToString();
			if (string.IsNullOrEmpty(strDateEnd))
				strDateEnd = DateTime.Now.ToString();

			DataSet ds_Select = Hipocrate.DB.DBConnection.GetData(dvReportMetadata[0]["ProcedureName"].ToString(), new string[] { "StartDate", "EndDate" }, new object[] { Convert.ToDateTime(strDateStart), Convert.ToDateTime(strDateEnd) }, false);
			return CreateHtmlObject(ds_Reports, ds_Select, out header, out title, out footer, out detailedEmptyTable);
		}

		/// <param name="detailedEmptyTable">Will return the possible contents of an empty report.
		///		Can be discarded, if a clean page is required.
		///		Can be added multiple times: see DuplicateControl.
		///	</param>
		public static HtmlGenericControl CreateHtmlObject(DataSet ds_Reports, DataSet ds_Select,
			out string header, out string title, out string footer, out HtmlGenericControl detailedEmptyTable)
		{
			HtmlGenericControl htmlControl = new HtmlGenericControl();
			header = string.Empty;
			title = string.Empty;
			footer = string.Empty;
			detailedEmptyTable = null;

			DataView dvReportMetadata = ds_Reports.Tables[1].DefaultView;
			DataView dvTableContents = null;
			#region Load dvTableContents
			if (ds_Select.Tables.Count > 0)
			{
				#region Add an Auto-Numbered Column, if required
				if (dvReportMetadata[0]["NumberColumn"] != System.DBNull.Value)
				{
					int column = (int)(dvReportMetadata[0]["NumberColumn"]) - 1;
					int nRows = ds_Select.Tables[0].Rows.Count;
					for (int row = 0; row < nRows; ++row)
						ds_Select.Tables[0].Rows[row][column] = row + 1;
				}
				#endregion
				dvTableContents = ds_Select.Tables[0].DefaultView;
			}
			#endregion

			char[] defaultSeparators = new char[] { ';' };
			string[] ColumnName = new string[] { };
			if (dvReportMetadata[0]["ColumnName"] != System.DBNull.Value)
				ColumnName = dvReportMetadata[0]["ColumnName"].ToString().Split(defaultSeparators, StringSplitOptions.RemoveEmptyEntries);

			if (dvReportMetadata[0]["ColumnSpanEnumeration"] != System.DBNull.Value)
				ColumnSpanEnumeration = dvReportMetadata[0]["ColumnSpanEnumeration"].ToString().Split(defaultSeparators, StringSplitOptions.RemoveEmptyEntries);

			string[] ColumnSum = new string[] { };
			if (dvReportMetadata[0]["ColumnSum"] != System.DBNull.Value)
				ColumnSum = dvReportMetadata[0]["ColumnSum"].ToString().Split(defaultSeparators, StringSplitOptions.RemoveEmptyEntries);

			string[] ColumnFormula = new string[] { };
			if (dvReportMetadata[0]["ColumnFormula"] != System.DBNull.Value)
				ColumnFormula = dvReportMetadata[0]["ColumnFormula"].ToString().Split(defaultSeparators);

			string[] ColumnSpanTitle = new string[] { };
			if (dvReportMetadata[0]["ColumnSpanTitle"] != System.DBNull.Value)
				ColumnSpanTitle = dvReportMetadata[0]["ColumnSpanTitle"].ToString().Split(defaultSeparators, StringSplitOptions.RemoveEmptyEntries);

			string[] HiddenColumn = new string[] { };
			if (dvReportMetadata[0]["HiddenColumns"] != System.DBNull.Value)
				HiddenColumn = dvReportMetadata[0]["HiddenColumns"].ToString().Split(defaultSeparators, StringSplitOptions.RemoveEmptyEntries);

			header = dvReportMetadata[0]["Header"].ToString();
			title = dvReportMetadata[0]["Title"].ToString();
			footer = dvReportMetadata[0]["Footer"].ToString();

			bool enableColumnSpan = Convert.ToBoolean(dvReportMetadata[0]["EnableColumnSpan"]);
			bool enableColumnFormula = Convert.ToBoolean(dvReportMetadata[0]["EnableColumnFormula"]);
			bool enableColumnTotal = Convert.ToBoolean(dvReportMetadata[0]["EnableColumnTotal"]);
			int nColumnCount = dvTableContents.Table.Columns.Count;

			bool isCustom = false;
			string customType = "";
			if (dvReportMetadata.Table.Columns.Contains("CustomReports"))
			{
				object request = dvReportMetadata[0]["CustomReports"];
				if ((request != DBNull.Value) && (request != null))
				{
					customType = request.ToString().Trim();
					isCustom = (customType.Length > 0);
				}
			}

			if (!isCustom)
				if (Convert.ToBoolean(dvReportMetadata[0]["MultipleReports"]) != true)
				{
					#region single report

					htmlControl.Controls.Add(new LiteralControl("<table border=\"1\" class=\"clsTable\" cellpadding=\"3\" cellspacing=\"0\" width=\"98%\">"));
					AddTableHeaders(ref htmlControl, nColumnCount, ColumnName, HiddenColumn, enableColumnSpan, ColumnSpanTitle, enableColumnFormula, ColumnFormula);

					// ITEMS
					if (dvTableContents.Count > 0)
					{
						#region create repeater
						Repeater Repeater1 = new Repeater();
						Repeater1.DataSource = dvTableContents;
						Repeater1.DataBind();

						foreach (RepeaterItem repeatItem in Repeater1.Items)
						{
							//RepeaterItem repeaterItem = new RepeaterItem(repeatItem.ItemIndex, ListItemType.Item);

							repeatItem.Controls.Add(new LiteralControl("<tr class=\"clsBlack\">"));

							for (int i = 0; i < nColumnCount; ++i)
								if (!HiddenColumn.Contains<string>((i + 1).ToString()))
								{
									repeatItem.Controls.Add(new LiteralControl("<td>"));
									repeatItem.Controls.Add(new LiteralControl(string.Format("{0} <br />", dvTableContents[repeatItem.ItemIndex][dvTableContents.Table.Columns[i].ColumnName])));
									repeatItem.Controls.Add(new LiteralControl("</td>"));
								}

							repeatItem.Controls.Add(new LiteralControl("</tr>"));
						}
						#endregion

						htmlControl.Controls.Add(Repeater1);
					}
					else
					{
						#region empty table
						PlaceHolder ph = new PlaceHolder();
						ph.ID = "EmptyTablePlaceholder";
						htmlControl.Controls.Add(ph);

						detailedEmptyTable = CreateEmptyTableContents(nColumnCount, HiddenColumn);
						#endregion
					}

					AddTableFooter(ref htmlControl, enableColumnTotal, ColumnSum, dvTableContents, nColumnCount, HiddenColumn);
					htmlControl.Controls.Add(new LiteralControl("</table>"));

					#endregion
				}
				else
				{
					#region multiple reports
					for (int i = 0; i < ds_Select.Tables.Count; ++i)
					{
						if (ds_Select.Tables.Count > 0)
						{
							DataView dv = ds_Select.Tables[i].DefaultView;
							if (dv.Count > 0)
							{
								Repeater Repeater1 = new Repeater();
								Repeater1.DataSource = dv;
								Repeater1.DataBind();

								if (dv[0]["nhp"].ToString() != string.Empty) // add title:
									Repeater1.Controls.Add(new LiteralControl("<div align=\"center\"><br/><b>" + dv[0]["nhp"].ToString() + " " + dv[0]["description"].ToString() + "</b></div>"));

								Repeater1.Controls.Add(new LiteralControl("<br /><br />"));

								// add subtitle:
								Repeater1.Controls.Add(new LiteralControl("<div><b><i>Factura nr. " + dv[0]["noInvoice"].ToString() + " din data " + Convert.ToDateTime(dv[0]["dateInvoice"]).ToString("dd.MM.yyyy") + "</i></b>"));

								DataTable dt = dv.Table;

								Repeater1.Controls.Add(new LiteralControl("<div align=\"right\"><b><i>Valoare totala factura:" + dt.Compute("SUM(totalValue_Articol)", null) + "</i></b></div></div>"));

								foreach (RepeaterItem repeatItem in Repeater1.Items)
								{
									//HEADER
									if (repeatItem.ItemIndex == 0)
									{
										//RepeaterItem headerItem = new RepeaterItem(repeatItem.ItemIndex, ListItemType.Header);

										repeatItem.Controls.Add(new LiteralControl("<table border=\"1\" class=\"clsTable\" cellpadding=\"3\" cellspacing=\"0\" width=\"98%\">"));

										repeatItem.Controls.Add(new LiteralControl("<tr class=\"clsBlack\">"));

										repeatItem.Controls.Add(new LiteralControl("<th>" + "Nr. Crt." + "</th>"));

										for (int j = 0; j < dt.Columns.Count; ++j)
										{
											bool tH = true;
											for (int x = 0; x < HiddenColumn.Length; ++x)
											{
												if (j == Convert.ToInt32(HiddenColumn[x]) - 1)
													tH = false;
											}

											if (tH == true)
											{
												LiteralControl ltrTh = new LiteralControl();
												if (ColumnName.Length < dt.Columns.Count - 5)
												{
													//TODO: remove magic number
													ltrTh.Text = "<th>" + "Incomplete columns" + "</th>";
												}
												else
													ltrTh.Text = "<th>" + Tools.UnPackCustomMarkup(ColumnName[j - 5]) + "</th>";
												repeatItem.Controls.Add(ltrTh);
											}
										}

										repeatItem.Controls.Add(new LiteralControl("</tr>"));
									}

									//ITEMS
									//RepeaterItem repeaterItem = new RepeaterItem(repeatItem.ItemIndex, ListItemType.Item);

									repeatItem.Controls.Add(new LiteralControl("<tr class=\"clsBlack\">"));

									repeatItem.Controls.Add(new LiteralControl("<td>"));
									repeatItem.Controls.Add(new LiteralControl(string.Format("{0} <br />", repeatItem.ItemIndex + 1)));
									repeatItem.Controls.Add(new LiteralControl("</td>"));

									for (int k = 0; k < dt.Columns.Count; ++k)
									{
										bool bItems = true;
										for (int x = 0; x < HiddenColumn.Length; ++x)
											if (k == Convert.ToInt32(HiddenColumn[x]) - 1)
												bItems = false;

										if (bItems)
										{
											repeatItem.Controls.Add(new LiteralControl(k == 5 ? "<td style=\"width: 60%\" >" : "<td>"));
											repeatItem.Controls.Add(new LiteralControl(string.Format("{0} <br />", dv[repeatItem.ItemIndex][dt.Columns[k].ColumnName])));
											repeatItem.Controls.Add(new LiteralControl("</td>"));
										}
									}

									repeatItem.Controls.Add(new LiteralControl("</tr>"));
								}

								//FOOTER
								//RepeaterItem repeaterFooter = new RepeaterItem(Repeater1.Items.Count - 1, ListItemType.Footer);

								htmlControl.Controls.Add(Repeater1);
								htmlControl.Controls.Add(new LiteralControl("</table>"));
							}
							else
							{
								// don't show empty tables
							}
						}
					}
					#endregion
				}
			else
			{
				#region Custom Report
				switch (customType)
				{
					case "OpisDrgSurgery":
						htmlControl.Controls.Add(new LiteralControl("<table border=\"1\" class=\"clsTable\" cellpadding=\"3\" cellspacing=\"0\" width=\"98%\">"));
						AddTableHeaders(ref htmlControl, nColumnCount, ColumnName, HiddenColumn, enableColumnSpan, ColumnSpanTitle, enableColumnFormula, ColumnFormula);

						//ITEMS
						if (dvTableContents.Count > 0)
						{
							#region create special repeater
							Repeater Repeater1 = new Repeater();
							Repeater1.DataSource = dvTableContents;
							Repeater1.DataBind();

							int nrCrt = 0;
							foreach (RepeaterItem repeatItem in Repeater1.Items)
							{
								bool isSamePerson = false;
								if (repeatItem.ItemIndex > 0)
									isSamePerson = object.Equals(dvTableContents[repeatItem.ItemIndex]["Nr_Reg"], dvTableContents[repeatItem.ItemIndex - 1]["Nr_Reg"]);
										//object.Equals(dvTableContents[repeatItem.ItemIndex]["Nr_Reg"], dvTableContents[repeatItem.ItemIndex - 1]["Nr_Reg"]) &&
										//object.Equals(dvTableContents[repeatItem.ItemIndex]["Pacient"], dvTableContents[repeatItem.ItemIndex - 1]["Pacient"]) &&
										//object.Equals(dvTableContents[repeatItem.ItemIndex]["CNP"], dvTableContents[repeatItem.ItemIndex - 1]["CNP"]);

								if (!isSamePerson)
								{
									repeatItem.Controls.Add(new LiteralControl("<tr class=\"clsBlack\">"));
									dvTableContents[repeatItem.ItemIndex]["NrCrt"] = ++nrCrt; //could technically use the "NumberColumn" meta-data, but why bother?
									for (int i = 0; i < nColumnCount; ++i)
										if (!HiddenColumn.Contains<string>((i + 1).ToString()))
										{
											repeatItem.Controls.Add(new LiteralControl("<td>"));
											repeatItem.Controls.Add(new LiteralControl(string.Format("{0} <br />", dvTableContents[repeatItem.ItemIndex][i])));
											repeatItem.Controls.Add(new LiteralControl("</td>"));
										}
									repeatItem.Controls.Add(new LiteralControl("</tr>"));
								}

								repeatItem.Controls.Add(new LiteralControl("<tr class=\"clsBlack\">"));

								bool isSameAppliedDate = (repeatItem.ItemIndex > 0) && object.Equals(dvTableContents[repeatItem.ItemIndex]["Details"], dvTableContents[repeatItem.ItemIndex - 1]["Details"]);
								isSameAppliedDate &= isSamePerson;
								if (isSameAppliedDate)
									repeatItem.Controls.Add(new LiteralControl("<td colspan=\"3\">&nbsp;</td>"));
								else
								{
									repeatItem.Controls.Add(new LiteralControl("<td colspan=\"2\">&nbsp;</td>"));
									repeatItem.Controls.Add(new LiteralControl("<td>"));
									repeatItem.Controls.Add(new LiteralControl(Tools.UnPackCustomMarkup(string.Format("{0} <br />", dvTableContents[repeatItem.ItemIndex]["Details"]))));
									repeatItem.Controls.Add(new LiteralControl("</td>"));
								}
								object quantity = dvTableContents[repeatItem.ItemIndex]["Quantity"];
								if ((quantity == DBNull.Value) || (quantity == null) || (quantity.ToString().Trim().Length == 0))
								{
									repeatItem.Controls.Add(new LiteralControl("<td colspan=\"4\" valign=\"top\">"));
									repeatItem.Controls.Add(new LiteralControl("&nbsp;Nu au fost configurate proceduri"));
									repeatItem.Controls.Add(new LiteralControl("</td>"));
								}
								else
								{
									repeatItem.Controls.Add(new LiteralControl("<td>"));
									repeatItem.Controls.Add(new LiteralControl(string.Format("{0} <br />", quantity)));
									repeatItem.Controls.Add(new LiteralControl("</td>"));
									repeatItem.Controls.Add(new LiteralControl("<td colspan=\"3\">"));
									string formatString = "{0} <br />";
									if (Convert.ToBoolean(dvTableContents[repeatItem.ItemIndex]["MainSurgery"]) == true)
										formatString = "<strong>{0}</strong> <br />";
									repeatItem.Controls.Add(new LiteralControl(string.Format(formatString, dvTableContents[repeatItem.ItemIndex]["Procedure"])));
									repeatItem.Controls.Add(new LiteralControl("</td>"));
								}

								repeatItem.Controls.Add(new LiteralControl("</tr>"));
							}
							#endregion

							htmlControl.Controls.Add(Repeater1);
						}
						else
						{
							#region empty table
							PlaceHolder ph = new PlaceHolder();
							ph.ID = "EmptyTablePlaceholder";
							htmlControl.Controls.Add(ph);

							detailedEmptyTable = CreateEmptyTableContents(nColumnCount, HiddenColumn);
							#endregion
						}

						//footer, non-standard:
						if (enableColumnTotal)
						{
							#region Add Row for Total
							htmlControl.Controls.Add(new LiteralControl("<tr class=\"clsBlack\">"));

							htmlControl.Controls.Add(new LiteralControl("<td align=\"right\" colspan=\"6\">"));
							htmlControl.Controls.Add(new LiteralControl("<b>TOTAL:</b>"));
							htmlControl.Controls.Add(new LiteralControl("</td>"));
							htmlControl.Controls.Add(new LiteralControl("<td>"));

							if (dvTableContents.Count > 0) //has data, compute sums
							{
								string targetColumn = "Quantity";
								if (dvTableContents.Table.Columns[targetColumn].DataType == Type.GetType("System.Int32") || dvTableContents.Table.Columns[targetColumn].DataType == Type.GetType("System.Decimal"))
									htmlControl.Controls.Add(new LiteralControl(string.Format("<b>" + dvTableContents.Table.Compute("SUM(" + targetColumn + ")", null).ToString() + "</b>")));
								else
									htmlControl.Controls.Add(new LiteralControl("<b>---<!-- not numeric --></b>"));
							}
							else // no data
								htmlControl.Controls.Add(new LiteralControl("<b>X</b>"));

							htmlControl.Controls.Add(new LiteralControl("</td>"));

							htmlControl.Controls.Add(new LiteralControl("</tr>"));
							#endregion
						}
						htmlControl.Controls.Add(new LiteralControl("</table>"));
						break;
					default:
						throw new ApplicationException("Unknown custom report type: " + customType);
				}
				#endregion
			}
			return htmlControl;
		}

		#region private helper functions
		private static HtmlGenericControl CreateEmptyTableContents(int nColumnCount, string[] HiddenColumn)
		{
			HtmlGenericControl result = new HtmlGenericControl();
			result.Controls.Add(new LiteralControl("<tr class=\"clsBlack\">"));

			for (int i = 0; i < nColumnCount; ++i)
				if (!HiddenColumn.Contains<string>((i + 1).ToString()))
				{
					result.Controls.Add(new LiteralControl("<td>"));
					result.Controls.Add(new LiteralControl(string.Format("{0} <br />", "No data...")));
					result.Controls.Add(new LiteralControl("</td>"));
				}

			result.Controls.Add(new LiteralControl("</tr>"));
			return result;
		}

		private static void AddTableHeaders(ref HtmlGenericControl htmlControl,
			int nColumnCount, string[] ColumnName, string[] HiddenColumn,
			bool enableColumnSpan, string[] ColumnSpanTitle,
			bool enableColumnFormula, string[] ColumnFormula)
		{
			#region First Row: Main Column Names
			htmlControl.Controls.Add(new LiteralControl("<tr class=\"clsBlack\">"));

			int delay = 0;
			for (int i = 0; i < nColumnCount; ++i)
				if (!HiddenColumn.Contains<string>((i + 1).ToString()))
				{
					if (enableColumnSpan)
					{
						if (HeaderInfo.Keys.Contains(i))
						{
							if (HeaderInfo[i] > 0)
							{
								int colSpan = HeaderInfo[i];
								htmlControl.Controls.Add(new LiteralControl(string.Format("<th colspan=\"{0}\">{1}</th>", colSpan, Tools.UnPackCustomMarkup(ColumnName[i - delay]))));
								delay += colSpan - 1;
							}
						}
						else // column is not part of any span, so set its header's rowspan to 2
						{
							LiteralControl th = new LiteralControl();
							if (ColumnName.Length <= i - delay)
								th.Text = "<th rowspan=\"2\"><font color=\"red\">" + "Incomplete columns" + "</font></th>";
							else
								th.Text = "<th rowspan=\"2\">" + Tools.UnPackCustomMarkup(ColumnName[i - delay]) + "</th>";
							htmlControl.Controls.Add(th);
						}
					}
					else // no spanning
					{
						LiteralControl ltrTh = new LiteralControl();
						if (ColumnName.Length < nColumnCount)
							ltrTh.Text = "<th>" + "Incomplete columns" + "</th>";
						else
							ltrTh.Text = "<th>" + Tools.UnPackCustomMarkup(ColumnName[i]) + "</th>";
						htmlControl.Controls.Add(ltrTh);
					}
				}

			htmlControl.Controls.Add(new LiteralControl("</tr>"));
			#endregion

			#region row for Sub-columns' headers
			if (enableColumnSpan)
			{
				htmlControl.Controls.Add(new LiteralControl("<tr>"));

				int index = 0;
				foreach (string columnTitle in ColumnSpanTitle)
				{
					if (++index > HeaderInfo.Keys.Count) break; // don't overflow the table...
					htmlControl.Controls.Add(new LiteralControl("<th>" + Tools.UnPackCustomMarkup(columnTitle) + "</th>"));
				}

				htmlControl.Controls.Add(new LiteralControl("</tr>"));
			}
			#endregion

			if (enableColumnFormula)
			{
				htmlControl.Controls.Add(new LiteralControl("<tr>"));

				for (int i = 0; i < nColumnCount; ++i)
				{
					LiteralControl ltrTdFormula1 = new LiteralControl();
					if (ColumnFormula.Length < nColumnCount)
						ltrTdFormula1.Text = "<td><b>" + "Incomplete columns" + "</b></td>";
					else
						ltrTdFormula1.Text = "<td><b>" + ColumnFormula[i] + "</b></td>";
					htmlControl.Controls.Add(ltrTdFormula1);
				}

				htmlControl.Controls.Add(new LiteralControl("</tr>"));
			}
		}

		private static void AddTableFooter(ref HtmlGenericControl htmlControl,
			bool enableColumnTotal, string[] ColumnSum, DataView dvTableContents,
			int nColumnCount, string[] HiddenColumn)
		{
			if (enableColumnTotal)
			{
				htmlControl.Controls.Add(new LiteralControl("<tr class=\"clsBlack\">"));

				for (int i = 0; i < nColumnCount; ++i)
					if (!HiddenColumn.Contains<string>((i + 1).ToString()))
					{
						htmlControl.Controls.Add(new LiteralControl("<td>"));

						if (i == 0)
							htmlControl.Controls.Add(new LiteralControl("<b>TOTAL:</b>"));
						else
						{
							if (dvTableContents.Count > 0) //has data, compute sums
							{ // check to see if summing was required for this column
								bool b = false;
								for (int j = 0; j < ColumnSum.Length; ++j)
								{
									if (i == Convert.ToInt32(ColumnSum[j]) - 1)
										b = true;
								}

								if (b == true)
									if (dvTableContents.Table.Columns[i].DataType == Type.GetType("System.Int32") || dvTableContents.Table.Columns[i].DataType == Type.GetType("System.Decimal"))
										htmlControl.Controls.Add(new LiteralControl(string.Format("<b>" + dvTableContents.Table.Compute("SUM(" + dvTableContents.Table.Columns[i].ColumnName + ")", null).ToString() + "</b>")));
									else
										htmlControl.Controls.Add(new LiteralControl("<b>---<!-- not numeric --></b>"));
								else
									htmlControl.Controls.Add(new LiteralControl("<b>X</b>"));
							}
							else // no data
								htmlControl.Controls.Add(new LiteralControl("<b>X</b>"));
						}

						htmlControl.Controls.Add(new LiteralControl("</td>"));
					}

				htmlControl.Controls.Add(new LiteralControl("</tr>"));
			}
		}
		#endregion

		/// <param name="detailedEmptyTable">Will return the possible contents of an empty report.
		///		Can be discarded, if a clean page is required.
		///		Can be added multiple times: see DuplicateControl.
		///	</param>
		public static HtmlGenericControl CreateHtmlObject(string strProcedureName, System.Collections.Specialized.NameValueCollection parameters,
			out string header, out string title, out string footer, out HtmlGenericControl detailedEmptyTable)
		{
			DataSet ds_Reports = Hipocrate.DB.DBConnection.GetData(strProcedureName, new string[] { "ID" }, new object[] { parameters["id"] });
			DataView dvReportMetadata = ds_Reports.Tables[1].DefaultView;
			System.Collections.Specialized.NameValueCollection arrayParams = new System.Collections.Specialized.NameValueCollection(parameters);
			arrayParams.Remove("id");
			DataSet ds_Select = GetCustomData(dvReportMetadata[0]["ProcedureName"].ToString(), arrayParams);
			return CreateHtmlObject(ds_Reports, ds_Select, out header, out title, out footer, out detailedEmptyTable);
		}
		public static DataSet GetCustomData(string procedureName, System.Collections.Specialized.NameValueCollection arrayParams)
		{
			object[] paramValues = new object[arrayParams.Count];
			for (int i = 0; i < arrayParams.Count; ++i)
			{
				string key = arrayParams.AllKeys[i];
				paramValues[i] = arrayParams[key];
				if (key.Equals("StartDate") || key.Equals("EndDate"))
					if (paramValues[i].Equals("null"))
						paramValues[i] = null;
					//else
					//	paramValues[i] = Convert.ToDateTime(paramValues[i]);
			}
			return Hipocrate.DB.DBConnection.GetData(procedureName, arrayParams.AllKeys, paramValues, false);
		}

		public static void GenerateFile(string fileName, string contentType, HttpContext context, string header, string title, HtmlGenericControl contents, string footer, HtmlGenericControl visiblyEmpty)
		{
			foreach (Control c in contents.Controls) if (string.Equals(c.ID, "EmptyTablePlaceholder")) { c.Controls.Add(visiblyEmpty); break; }

			LiteralControl ltrHeader = null, ltrTitleX = null, ltrFooter = null;
			ltrHeader = new LiteralControl("<div>" + header + "</div><br/>");
			ltrTitleX = new LiteralControl("<div align=\"center\">" + title + "</div><br/>");
			ltrFooter = new LiteralControl("<div>" + footer + "</div>");

			context.Response.Clear();
			context.Response.AddHeader("content-disposition", "attachment;filename=" + ExportTools.CommonExport.TrimFileName(fileName));
			context.Response.Charset = "";
			context.Response.ContentType = contentType;
			System.IO.StringWriter stringWrite = new System.IO.StringWriter();
			HtmlTextWriter htmlWrite = new HtmlTextWriter(stringWrite);
			ltrHeader.RenderControl(htmlWrite);
			ltrTitleX.RenderControl(htmlWrite);
			contents.RenderControl(htmlWrite);
			//check for (and fix if needed) missing end tag for the previous repeater:
			if (!stringWrite.ToString().Trim().EndsWith("</table>"))
				stringWrite.Write("</table>");
			ltrFooter.RenderControl(htmlWrite);
			context.Response.Write(stringWrite.ToString());
		}

		/// <summary>
		/// Shrinks a file URI (which might or might not contain any path info) to retrieve only the fileName
		/// </summary>
		/// <param name="fileName"></param>
		/// <returns></returns>
		public static string TrimFileName(string fileName)
		{
			if (fileName.Contains('\\'))
				fileName = fileName.Substring(fileName.LastIndexOf('\\') + 1);
			if (fileName.Contains('/'))
				fileName = fileName.Substring(fileName.LastIndexOf('/') + 1);
			return fileName;
		}

		public static void ErrorOut(HttpContext context, Exception ex)
		{
			ErrorOut(context, ex.Message + "<!-- " + ex.ToString() + " -->");
		}
		public static void ErrorOut(HttpContext context, string message)
		{
			context.Response.ClearContent();
			context.Response.ClearHeaders();
			context.Response.Clear();
			context.Response.Write("<b style='color: Red'>" + message + "</b>");
			context.Response.Flush();
			context.Response.Close();
		}

		public static HtmlGenericControl DuplicateControl(HtmlGenericControl template)
		{
			HtmlGenericControl result = new HtmlGenericControl();
			foreach (LiteralControl c in template.Controls) result.Controls.Add(new LiteralControl(c.Text));
			return result;
		}

		public static void UnPackCustomMarkup(ref string header, ref string title, ref string footer, System.Collections.Specialized.NameValueCollection parameters)
		{
			header = UnPackCustomMarkup(header, parameters);
			title = UnPackCustomMarkup(title, parameters);
			footer = UnPackCustomMarkup(footer, parameters);
		}
		public static System.Collections.Specialized.NameValueCollection GetDefaultParams(string startDate, string endDate)
		{
			if (string.IsNullOrEmpty(startDate))
				startDate = DateTime.Now.ToString();
			if (string.IsNullOrEmpty(endDate))
				endDate = DateTime.Now.ToString();
			System.Collections.Specialized.NameValueCollection parameters = new System.Collections.Specialized.NameValueCollection(2);
			parameters.Add("StartDate", startDate);
			parameters.Add("EndDate", endDate);
			return parameters;
		}
		public static string UnPackCustomMarkup(string source, System.Collections.Specialized.NameValueCollection parameters)
		{
			return UnPackParameters(Tools.UnPackCustomMarkup(source), parameters);
		}
		public static string UnPackCustomMarkupForPdf(string source, System.Collections.Specialized.NameValueCollection parameters)
		{
			return UnPackParameters(Tools.UnPackCustomMarkupForPdf(source), parameters);
		}
		private static string UnPackParameters(string source, System.Collections.Specialized.NameValueCollection parameters)
		{
			string result = source;
			foreach (string key in parameters.Keys)
				if (result.Contains("@" + key))
					result = result.Replace("@" + key, parameters[key]);
			return result;
		}
	}
}
